package ru.stepuk.modern.nodes.buffers;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.swing.JDialog;
import ru.stepuk.modern.InvalidModelException;
import ru.stepuk.modern.Model;
import ru.stepuk.modern.nodes.Node;
import ru.stepuk.modern.Request;
import ru.stepuk.modern.gui.SetBufferCapcityDialog;
import ru.stepuk.modern.nodes.servers.PriorityServer;
import ru.stepuk.modern.nodes.servers.Server;

/**
 *
 * @author Ivan Stepuk
 */
public abstract class Buffer extends Node {

    protected int capacity;
    protected List<Request> container;
    protected List<Server> servers = new ArrayList<Server>();

    public abstract Request fetchRequest();

    public abstract void putRequest(Request request);

    public boolean hasFreeSpace() {
        if (capacity == 0) {
            return true;
        }
        return container.size() < capacity;
    }

    public Buffer(Model model) {
        super(model);
    }

    public int getCapacity() {
        return capacity;
    }

    public void setCapacity(int capacity) {
        this.capacity = capacity;
    }

    public boolean isEmpty() {
        return container.isEmpty();
    }

    public void processRequest(Request request) {
        System.out.println(": " + name + "request come to buffer");
        // Lookup 4 free servers
        for (Server s : servers) {
            if (s.isIdle()) {
                System.out.println(": " + name + "request redirected to server");
                s.processRequest(request);
                
                return;
            }
        }
        // Interruption
        for (Server s : servers) {
            if ((s instanceof PriorityServer) && (s.getCurrentRequest().getPriority() < request.getPriority())) {
                System.out.println(": " + name + "request interrupted server");
                s.processRequest(request);
                
                return;
            }
        }

        servers.get(0).processRequest(request);
        System.out.println(": " + name + "request FORCES server");
    }

    public void validate() throws InvalidModelException {
        container.clear();
        servers.clear();

        if (model.getNextNodes(this).size() == 0) {
            throw new InvalidModelException(this.name + ": No out from node");
        } else {
            for (Iterator<Node> it = model.getNextNodes(this).iterator(); it.hasNext();) {
                try {
                    servers.add((Server) it.next());
                } catch (ClassCastException ex) {
                    throw new InvalidModelException("Next to buffer not server");
                }
            }
        }
    }

    public JDialog getPropertiesDialog() {
        return new SetBufferCapcityDialog(this);
    }
}
